package edu.dayu.listener;

import com.rabbitmq.client.Channel;
import edu.dayu.constant.MqConstant;
import edu.dayu.entity.pojo.MsgRecord;
import edu.dayu.mapper.MsgRecordMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.amqp.support.AmqpHeaders;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.messaging.handler.annotation.Header;
import org.springframework.messaging.handler.annotation.Payload;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.concurrent.TimeUnit;

@Component
@Slf4j
public class TestListener {

    @Autowired
    private MsgRecordMapper msgRecordMapper;

    @Autowired
    private RedisTemplate<String,Object> redisTemplate;

    @RabbitListener(queues = MqConstant.QUEUE_TEST1,
            ackMode = "MANUAL"
    )
    public void test1(Channel channel,
                         @Header(AmqpHeaders.DELIVERY_TAG) long deliveryTag,
                         @Header(value = "mid") long mid,
                         @Payload String message){
        if (!idempotent(channel,deliveryTag,mid)){
            return;
        }
        log.info("test1队列，收到消息{}",message);
        try {
            channel.basicAck(deliveryTag,false);
            MsgRecord record = new MsgRecord();
            record.setId(mid);
            record.setStatus(3);
            msgRecordMapper.updateById(record);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @RabbitListener(
            queues = MqConstant.QUEUE_TEST3,
            ackMode = "MANUAL")
    public void test3(Channel channel,
                      @Header(AmqpHeaders.DELIVERY_TAG) long deliveryTag,
                      @Header(value = "mid") long mid,
                      @Payload String message){
        if (!idempotent(channel,deliveryTag,mid)){
            return;
        }
        log.info("死信队列，收到消息{}",message);
        try {
            channel.basicAck(deliveryTag,false);
            MsgRecord record = new MsgRecord();
            record.setId(mid);
            record.setStatus(3);
            msgRecordMapper.updateById(record);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 幂等
     */
    private boolean idempotent(Channel channel,long deliveryTag,long mid){
        // 这个过期时间需要根据自己的需求来进行设计，详细参照资料的幂等设计
        Boolean flag = redisTemplate.opsForValue().setIfAbsent("Mid:" + mid, 1, 30, TimeUnit.SECONDS);
        if (Boolean.FALSE.equals(flag)){
            try {
                channel.basicAck(deliveryTag,false);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return flag;
    }

}
